<?php

class DBStore {

    private $db_config = [];
    private $driver_store = [];

    public function __construct() {
        $this->db_config = getInstance()->config['db'];
    }

    public function _instance($dbname, $newConnect = FALSE) {
        if (!is_string($dbname)) {
            throw new \Exception('invalid database name');
        }

        if (!isset($this->driver_store[$dbname])) {
            $this->driver_store[$dbname] = $this->_connect($dbname);
            return $this->driver_store[$dbname];
        }

        $newConnect && $this->_newConnect();
        return $this->driver_store[$dbname];
    }

    private function _connect($dbname) {
        if (!isset($this->db_config[$dbname])) {
            throw new \Exception(sprintf('database[%s] does not exist'));
        }

        $db = $this->db_config[$dbname];
        $con = mysqli_connect($db['host'], $db['user'], $db['pwd'], $dbname, $db['port'], $db['mysql_sock']);
        if (!$con) {
            throw new \Exception(sprintf('database[%s] connecting come out error[%s]', $dbname, mysqli_connect_error()));
        }

        mysqli_autocommit($con, TRUE);
        mysqli_set_charset($con, $db['charset']);
        return new DBDriver($con);
    }

    private function _newConnect() {
        if (!isset($this->driver_store[$dbname])) {
            throw new \Exception('system[dbstore] come out error');
        }

        $db = $this->db_config[$dbname];
        $con = $this->driver_store[$dbname]->con;
        if (mysqli_real_connect($con, $db['host'], $db['user'], $db['pwd'], $dbname, $db['port'], $db['mysql_sock'])) {
            mysqli_autocommit($con, FALSE);
            mysqli_set_charset($con, $db['charset']);
            $this->driver_store[$dbname] = new DBDriver($con);
            return;
        }

        throw new \Exception(sprintf('database[%s] creating a new connect come out error[%s]', $dbname, mysqli_connect_error()));
    }

    public function __destruct() {
        if (!$this->driver_store || !is_array($this->driver_store)) {
            return;
        }

        foreach ($this->driver_store as $_db) {
            mysqli_close($_db->con);
        }
    }
}

class DBDriver {

    public $con;

    public function __construct($dbcon) {
        $this->con = $dbcon;
    }

    public function _insert($tablename, array $insertData) {
        if (!$insertData) {
            return 0;
        }

        $fields = $values = [];
        foreach ($insertData as $_k => $_v) {
            $fields[] = $this->filterField($_k);
            $values[] = $this->filterValue($_v);
        }

        if (!$fields || !$values) {
            return 0;
        }

        $sql = sprintf('INSERT INTO %s (%s) VALUES (%s)', $tablename, implode(',', $fields), implode(',', $values));
        if (mysqli_query($this->con, $sql)) {
            return mysqli_insert_id($this->con);
        } else {
            throw new \Exception($this->con->error);
        }
    }

    public function filterField($field) {
        return sprintf('`%s`', $field);
    }

    public function filterValue($value) {
        if (is_string($value)) {
            return sprintf('"%s"', mysqli_real_escape_string($this->con, $value));
        } else {
            return $value;
        }
    }
}
